package com.ruoyi.wechat.api;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpInteractionUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * 
 * @name：WechatApi.java
 * @description：微信公众号API
 * @author Administrator
 * @since 2017年11月14日
 *
 */
@Component
//@ConfigurationProperties(prefix = "com.zyd")
@PropertySource(value = { "classpath:wechat.properties" })
public class WechatApi {
	/**
	 * 静态变量、类变量不是对象的属性，而是一个类的属性，
	 * 所以静态方法是属于类（class）的，普通方法才是属于实体对象（也就是New出来的对象）的，
	 * spring注入是在容器中实例化对象，所以不能使用静态方法。
	 */
	private static Environment env; 
	
//	private static MemCachedClient memClient;
	
	public static String getMpAppid(){
		return env.getProperty("gzhAppId");
	}
	/**
	 * 成为开发者验证服务器地址
	 * 
	 * @param timestamp
	 *            时间 wechat返回
	 * @param nonce
	 *            随机数 wechat返回
	 * @return
	 */
	public static String validateServiceUrl(String timestamp, String nonce) {
		String token = env.getProperty("KFZToken");
		ArrayList<String> list = new ArrayList<String>();
		list.add(nonce);
		list.add(timestamp);
		list.add(token);

		Collections.sort(list);
		String result = DigestUtils.sha1Hex(String.format("%s%s%s", list.get(0), list.get(1), list.get(2)));
		return result;
	}

	/**
	 * 获得用户授权
	 * 
	 * @return
	 */
	public static String getWechatAsstokenUrl(String redirect_uri) {
		String appid = env.getProperty("gzhAppId");
		String scope = "snsapi_userinfo";
		String state = "100";
		String domain = env.getProperty("domain");
		try {
			redirect_uri = URLEncoder.encode(domain + redirect_uri, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return String.format(
				"https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect",
				appid, redirect_uri, scope, state);
	}

	/**
	 * 通过code换取网页授权access_token
	 * 
	 * @param code
	 * 
	 * @return
	 */
	public static String getAccessToken(String code) {
		String appid = env.getProperty("gzhAppId");
		String secret = env.getProperty("AppSecret");
		return String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", appid,
				secret, code);

	}

	/**
	 * 获取公众号的access_token,该token不是用户token
	 * 
	 * @return
	 */
	public static String access_token() {
		String access_token = null;//(String) memClient.get(memClient.get("KFZToken")+Constants.WECHAT__ACCESS_TOCKEN);
		if (StringUtils.isEmpty(access_token)) {
			String appid = env.getProperty("gzhAppId");
			String secret = env.getProperty("AppSecret");
			String sendUrl = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, secret);
			String resultJson = HttpInteractionUtil.getDate(sendUrl, "utf-8");
			JSONObject jsonObject = JSONObject.parseObject(resultJson);
			if (jsonObject == null) {
				throw new BusinessException("微信公众号获取用户信息失败");
			}

			access_token = jsonObject.getString("access_token");
			String expires_in = jsonObject.getString("expires_in");// 有效期（秒）
			//memClient.add(memClient.get("KFZToken")+Constants.WECHAT__ACCESS_TOCKEN, access_token,new Date(Integer.valueOf(expires_in) * 1000 - 10));
		}
		return access_token;
	}

	/**
	 * 拉取用户信息 用户可不用关注公众号
	 * 
	 * @param access_token
	 *            网页授权接口调用凭证,注意：此access_token与基础支持的access_token不同
	 * @param openid
	 * @return
	 */
	public static String snsapiUserinfo(String access_token, String openid) {
		return String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN ", access_token, openid);
	}

	/**
	 * 拉取用户信息，用户必须关注公众号 包括UnionID机制
	 * 
	 * @param openid
	 * @return
	 */
	public static String userInnfo(String openid) {
		return String.format("https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s", access_token(), openid);
	}

	/**
	 * 验证token是否有效
	 * 
	 * @param access_token
	 * @param openid
	 * @return
	 */
	public static String ACCESS_TOKEN(String access_token, String openid) {
		return String.format("https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s", access_token, openid);

	}

	/**
	 * 刷新token
	 * 
	 * @param refresh_token
	 * @return
	 */
	public static String REFRESH_TOKEN(String refresh_token) {
		String appid = env.getProperty("gzhAppId");
		return String.format("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s", appid,
				refresh_token);
	}

	/**
	 * 自定义菜单创建接口(post请求)
	 * 
	 * @return
	 */
	public static String create_menu() {
		return String.format("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s", access_token());
	}

	/**
	 * 自定义菜单删除接口
	 * 
	 * @return
	 */
	public static String delete_menu() {
		return String.format("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=%s", access_token());
	}
	
	/**
	 * 获取自定义菜单
	 * @return
	 */
	public static String get_menu(){
		return String.format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token=%s", access_token());
	}

	/**
	 * 推送模板消息
	 * 
	 * @return
	 */
	public static String send_template_msg() {
		return String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", access_token());
	}
	

	/**
	 * 根据access_token获取jsapi_ticket：
	 * 
	 * @return
	 */
	public static String get_ticket() {
		//MemcachedLive.getInstance().delete(Constants.WECHAT__ACCESS_TOCKEN);
		String ticket = null;//(String) memClient.get(Constants.WECHAT__ACCESS_TOCKEN);
		if (StringUtils.isEmpty(ticket)) {
			String sendUrl = String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi", access_token());
			String resultJson = HttpInteractionUtil.executeHttpGet(sendUrl);
			JSONObject jsonObject = JSONObject.parseObject(resultJson);
			if (jsonObject == null) {
				throw new BusinessException("微信公众号获取用户信息失败");
			}
			ticket = jsonObject.getString("ticket");
			String expires_in = jsonObject.getString("expires_in");// 有效期（秒）
			//memClient.add(Constants.WECHAT__ACCESS_TOCKEN, ticket, new Date(Integer.valueOf(expires_in) * 1000 - 10));
		}
		return ticket;
	}

	/**
	 * 使用JSSDK中需要用到的参数
	 * 
	 * @param url
	 * @return
	 */
	public static Map<String, String> getSdkParams(String url) {
		Map<String, String> result = new HashMap<String, String>();
		String jsapi_ticket = get_ticket();
		String nonce_str = UUID.randomUUID().toString();
		String timestamp = Long.toString(System.currentTimeMillis() / 1000);
		String string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url;

		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			String signature = byteToHex(crypt.digest());

			result.put("url", url);
			result.put("jsapi_ticket", jsapi_ticket);
			result.put("nonceStr", nonce_str);
			result.put("timestamp", timestamp);
			result.put("signature", signature);
			result.put("appid", env.getProperty("gzhAppId"));

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return result;
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}
	
	 //随机字符串生成  
    public static String getRandomString(int length) { //length表示生成字符串的长度      
         String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";         
         Random random = new Random();         
         StringBuffer sb = new StringBuffer();         
         for (int i = 0; i < length; i++) {         
             int number = random.nextInt(base.length());         
             sb.append(base.charAt(number));         
         }         
         return sb.toString();         
    }  
    
    

	public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		String string1 = "jsapi_ticket=HoagFKDcsGMVCIY2vOjf9qxCw46hU3Z4mkDjScP4QMht3eoVAj1Tphyzzb4UxM_SI24FMqh5s4a4Evb4mT_p2Q&noncestr=0e182a9c-315a-4e94-b38b-8d859af2dcd2&timestamp=1511624798&url=http://192.168.0.100:8181/wechatsdk/share.htm";
		MessageDigest crypt = MessageDigest.getInstance("SHA-1");
		crypt.reset();
		crypt.update(string1.getBytes("UTF-8"));
		String signature = byteToHex(crypt.digest());
		System.out.println(signature);
	}

	public static Environment getEnv() {
		return env;
	}

	@Autowired
	public void setEnv(Environment env) {
		WechatApi.env = env;
	}

//	public static MemCachedClient getMemClient() {
//		return memClient;
//	}

//	@Autowired
//	public void setMemClient(MemCachedClient memClient) {
//		WechatApi.memClient = memClient;
//	}
	
	
	
}
